.486p
.model flat
.code

        include data.h
        include main.h
        include empty.h
        include gui.h
        include vga.h
        include config.h

        public vesainit
        public vesaexit
        public m320x240
        public m320x480
        public m640x480
;----------------------------------------------------------------------------
vesainit:;      in:
;                       ?
;               out:
;                       ?
;----------------------------------------------------------------------------
      ;  xor ecx,ecx
      ;  mov cx,ds
      ;  lsl ecx,ecx

        mov edi,[dos_ptr]
        mov [edi],"2EBV"
        add edi,[code_addr]
        shr edi,4
        mov [_es],di
        mov [_edi],0
        mov [_eax],4f00h

        mov ax,300h
        mov bx,10h
        xor ecx,ecx
        mov edi,offset reg_struc
        int 31h                         ;get VBE info
        jc vi99
        cmp [_eax],4fh
        jne vi99

        mov edi,[dos_ptr]
        movzx eax,[edi+totmem]          ;get mem size
        mov [vesamem],eax

        movzx esi,word ptr [edi+modelistptr+2]
        movzx ebx,word ptr [edi+modelistptr]
        shl esi,4
        add esi,ebx
        sub esi,[code_addr]
        mov edi,offset vesamodes
        mov ecx,512/4
        rep movsd                       ;copy mode list

        mov [_eax],4f0ah
        mov [_ebx],0
        mov ax,300h
        mov bx,10h
        xor ecx,ecx
        mov edi,offset reg_struc
        int 31h                         ;get PM interface
        jc vi99
        cmp [_eax],4fh
        jne vi99

        movzx eax,word ptr [_es]
        movzx ebx,word ptr [_edi]
        shl eax,4
        add eax,ebx
        sub eax,[code_addr]
        movzx ebx,word ptr [eax+2]
        add eax,ebx
        mov [fn_7],eax                  ;get function 7 call (set display start)

        mov eax,320                     ;now find some modes
        mov ebx,240
        mov cl,8
        call findmode
        jnc vi0
        or [m3txt],80h                          ;disable GUI option
vi0:
        mov eax,320
        mov ebx,480
        mov cl,8
      ;  call findmode
      ;  jnc vi1
        or [m4txt],80h
vi1:
        mov eax,640
        mov ebx,480
        mov cl,32
      ;  call findmode
      ;  jnc vi2
        or [m5txt],80h
vi2:

vi99:
        ret
;----------------------------------------------------------------------------
vesaexit:;              setmode calls this too
;----------------------------------------------------------------------------
        mov eax,[savebx]
        or eax,[savecx]
        jz ve9
        mov eax,801h
        mov ebx,[savebx]
        mov ecx,[savecx]
        int 31h                 ;free LFB mapping
        xor eax,eax
        mov [savebx],eax
        mov [savecx],eax
ve9:
        ret
;----------------------------------------------------------------------------
findmode:;
;       in:
;               eax=width
;               ebx=height
;               cl=bpp
;       out:
;               edx=mode
;               [dos_ptr]=infoblok
;               CF=0 on success
;               lots of stuff destroyed
;----------------------------------------------------------------------------
        mov esi,offset vesamodes
fm0:        
        movsx edx,word ptr [esi]        ;run thru mode list..
        or edx,edx
        js fm99
        add esi,2

        push eax
        push ebx
        push ecx

        mov edi,[dos_ptr]
        mov [_ecx],edx
        push edi
        add edi,[code_addr]
        shr edi,4
        mov [_es],di
        mov [_edi],0
        mov [_eax],4f01h
        mov ax,300h
        mov bx,10h
        xor ecx,ecx
        mov edi,offset reg_struc
        int 31h                         ;get modeinfoblock

        pop edi
        pop ecx
        pop ebx
        pop eax

        jc fm99
        cmp dword ptr [_eax],4fh
        jne fm99

        cmp [edi+xres],ax
        jne fm0
        cmp [edi+yres],bx
        jne fm0
        cmp [edi+bpp],cl
        jne fm0
        test byte ptr [edi+modeattr],81h        ;LFB and mode supported?
        jz fm0
        jnp fm0                                 ;(modeattr&81==81)
        clc
        ret
fm99:
        stc
        ret
;----------------------------------------------------------------------------
setmode:;
;               in:
;                       same as findmode
;----------------------------------------------------------------------------
        call findmode
        jc sm99

	;code to check size and set bytes_per_page was here

        mov eax,4f02h
        mov ebx,edx
        or ebx,4000h            ;want LFB
        int 10h
        cmp eax,4fh
        jne sm99

        call vesaexit           ;free old mapping
        mov edi,[dos_ptr]
        movzx eax,[edi+BytesPerScanLine]
        mov [linesize],eax
        mov ebx,[edi+fiz_base_point]
        mov ecx,ebx
        shr ebx,16
        mov esi,[vesamem]
        xor edi,edi
        mov ax,0800h            ;map physical mem
        int 31h
        jc sm99

        mov [savebx],ebx
        mov [savecx],ecx
        shl ebx,16
        mov bx,cx
        sub ebx,[code_addr]
        mov [lfb],ebx           ;got our LFB

     ;   add ebx,bytes_per_page
     ;   mov [lfb2],ebx         ;page 2
     ;   mov llama_linear,ebx    ;where to draw
   ; mov yoko,0
   ; ;set up cx and dx for scr2 select
   ; mov edx,bytes_per_page
   ; shr edx,2
   ; mov cx,dx
   ; shr edx,16
   ; mov cx_scr2,cx
   ; mov dx_scr2,dx

        clc
        ret
sm99:   
        stc
        ret
;----------------------------------------------------------------------------
m320x240:;
m320x480:;
;----------------------------------------------------------------------------
        mov [pageflip],offset d320x240
        mov eax,320
        mov ebx,240
        mov cl,8
        call setmode
        jc badmode

        mov eax,[linesize]
        sub eax,256
        mov [size1],eax

        mov eax,0f0f0f0f0h              ;clear borders
        mov edi,[lfb]
        mov edx,240
m3201:  mov ecx,8
m3200:  mov [edi],eax
        mov [edi+32+256],eax
        add edi,4
        dec ecx
        jnz m3200
        sub edi,32
        add edi,[linesize]
        dec edx
        jnz m3201

        jmp setpal
badmode:
        mov [vidmode],0         ;(revert to crap mode)
        jmp gfxmode
;----------------------------------------------------------------------------
d320x240:
;----------------------------------------------------------------------------
;        call vret

        cmp [newborder],0
        je m10
                                ;border setup --------
        dec [newborder]
        mov eax,0f0f0f0f0h               ;clear everything
        mov edi,[lfb]
        mov edx,240
m11:    mov ecx,[linesize]
m12:    mov [edi],eax
        add edi,4
        sub ecx,4
        jnz m12
        dec edx
        jnz m11

        mov esi,offset vscreen+8        ;setup vars
        xor edi,edi
        mov edx,240

        cmp [border0],0
        je m13
        sub edx,8
        add edi,4
        add esi,8*264
m13:
        cmp [border232],0
        je m14
        sub edx,8
        add edi,4
m14:
        mov dword ptr [m1src+1],esi                 ;SMC rules
        mov dword ptr [m1size+1],edx
        mov eax,[linesize]
        mul edi
        add eax,32
        mov dword ptr [m1dst+1],eax
m10:                            ;dump screen ---------
m1src:  mov esi,offset vscreen+8+8*264
m1dst:  mov edi,8*320+32
m1size: mov edx,224
        add edi,[lfb]

d3200:  mov ecx,256/8
d3201:  mov eax,[esi]
        mov ebx,[esi+4]
        add esi,8
        mov [edi],eax
        mov [edi+4],ebx
        add edi,8
        dec ecx
        jnz d3201
        add esi,8
        add edi,[size1]
        dec edx
        jnz d3200
        ret
;----------------------------------------------------------------------------
m640x480:
;----------------------------------------------------------------------------
        mov [_8bit],0
        mov [pageflip],offset d640x480
        mov eax,640
        mov ebx,480
        mov cl,32
        call setmode
        jc badmode

        mov eax,[linesize]
        shl eax,1
        sub eax,512*4
        mov [size1],eax
cls640:
        mov ebx,[linesize]
        mov eax,480/4
        mul ebx
        mov ecx,eax
        xor eax,eax
        mov edi,[lfb]
        rep stosd
        ret
;----------------------------------------------------------------------------
d640x480:
;----------------------------------------------------------------------------
;        call vret

        cmp [newborder],0
        je m50
                                ;border setup --------
        dec [newborder]
        call cls640
        mov esi,offset vscreen+8        ;setup vars
        xor edi,edi
        mov edx,240

        cmp [border0],0
        je m53
        sub edx,8
        add edi,8
        add esi,8*264
m53:
        cmp [border232],0
        je m54
        sub edx,8
        add edi,8
m54:
        mov dword ptr [m5src+1],esi                 ;SMC rules
        mov dword ptr [m5size+1],edx
        mov eax,[linesize]
        mul edi
        add eax,64*4
        mov dword ptr [m5dst+1],eax
m50:                            ;dump screen ---------
m5src:  mov esi,offset vscreen+8+8*264
m5dst:  mov edi,8*320+32
m5size: mov edx,224
        add edi,[lfb]
        mov [poo],edx

        xor eax,eax
        xor ebx,ebx
d6400:  mov ebp,256
d6401:
        mov al,[esi]
        mov edx,[fullpal+eax*4]
        shl edx,1
        mov al,[esi+1]
        add edx,[fullpal+eax*4]
        mov al,[esi+264]
        add edx,[fullpal+eax*4]
           bswap edx
           shr edx,8
           mov [edi],edx
        mov al,[esi+1]
        mov edx,[fullpal+eax*4]
        shl edx,1
        mov al,[esi]
        add edx,[fullpal+eax*4]
        mov al,[esi+265]
        add edx,[fullpal+eax*4]
           bswap edx
           shr edx,8
           mov [edi+4],edx
        mov al,[esi+264]
        mov edx,[fullpal+eax*4]
        shl edx,1
        mov al,[esi]
        add edx,[fullpal+eax*4]
        mov al,[esi+265]
        add edx,[fullpal+eax*4]
           bswap edx
           shr edx,8
           mov [edi+640*4],edx
        mov al,[esi+265]
        mov edx,[fullpal+eax*4]
        shl edx,1
        mov al,[esi+1]
        add edx,[fullpal+eax*4]
        mov al,[esi+264]
        add edx,[fullpal+eax*4]
           bswap edx
           shr edx,8
           mov [edi+640*4+4],edx


        inc esi
        add edi,8
        dec ebp
        jnz d6401
        add esi,8
        add edi,[size1]
        dec [poo]
        jnz d6400
        ret
poo dd ?
;----------------------------------------------------------------------------
        align 4

fn_7            dd ?                    ;call ptr
vesamem         dd ?                    ;total memory*64k
lfb             dd ?
linesize        dd ?                    ;logical scanline 
size1           dd ?                    ;(mode specific)
;size2           dd ?

savebx          dd 0
savecx          dd 0

infoblok struc
  sig db 'VBE2'           ;VBE Signature
  vbever dw 0             ;VBE Version
  text_ptr1 dd 0          ;Pointer to OEM String
  Capabilities dd 0       ;Capabilities of graphics cont.
  modelistptr dd 0        ;Pointer to Video Mode List 
  totmem dw 0             ;Number of 64kb memory blocks
  softver dw 0            ;VBE implementation Software revision
  text_ptr2 dd 0          ;Pointer to Vendor Name String
  text_ptr3 dd 0          ;Pointer to Product Name String
  text_ptr4 dd 0          ;Pointer to Product Revision String
  db 222 dup (0)          ;Reserved for VBE implementation scratch area
  OemData db 256 dup (0)  ;Data Area for OEM Strings
ends

modeblok struc
  modeattr dw 0                 ;mode attributes
  WinAAttributes db 0           ;window A attributes
  WinBAttributes db 0           ;window B attributes
  WinGranularity dw 0           ;window granularity
  WinSize dw 0                  ;window size
  WinASegment dw 0              ;window A start segment
  WinBSegment dw 0              ;window B start segment
  WinFuncPtr dd 0               ;pointer to window function
  BytesPerScanLine dw 0         ;bytes per scan line
  xres dw 0                     ;horizontal resolution in pixels or chars
  yres dw 0                     ;vertical resolution in pixels or chars
  XCharSize db 0                ;character cell width in pixels
  YCharSize db 0                ;character cell height in pixels
  NumberOfPlanes db 0           ;number of memory planes
  bpp db 0                      ;bits per pixel
  NumberOfBanks db 0            ;number of banks
  MemoryModel db 0              ;memory model type
  BankSize db 0                 ;bank size in KB
  numpages db 0                 ;number of image pages
  db 0                          ;reserved for page function
  RedMaskSize db 0              ;size of direct color red mask in bits
  RedFieldPosition db 0         ;bit position of lsb of red mask
  GreenMaskSize db 0            ;size of direct color green mask in bits
  GreenFieldPosition db 0       ;bit position of lsb of green mask
  BlueMaskSize db 0             ;size of direct color blue mask in bits
  BlueFieldPosition db 0        ;bit position of lsb of blue mask
  RsvdMaskSize db 0             ;size of direct color reserved mask in bits
  RsvdFieldPosition db 0        ;bit position of lsb of reserved mask
  DirectColorModeInfo db 0      ;direct color mode attributes
  fiz_base_point dd 0           ;physical address for flat frame buffer
  offscreen dd 0                ;pointer to start of off screen memory
  OffScreenMemSize dw 0         ;amount of off screen memory in 1k units
  db 206 dup (0)                ;remainder of ModeInfo
ends

;----------------------------------------------------------------------------
        end

